<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="ZUI，一个简单灵活的前端框架。">
    <meta name="author" content="Zentao">
    <title>ZUI - KindEditor 自定义 Holder 插件</title>
    <link href="../../dist/css/zui.css" rel="stylesheet">
</head>

<body style="padding: 20px">
    <div class="container" id="contextmenuExample">
        <div class="article-content">
            <h1>KindEditor 自定义工具例子</h1>
            <p>Holder 插件能够在编辑器内插入自定义内容，这些自定义内容包含隐藏的文本和在界面上实际显示的文本，并且实际显示的文本无法直接编辑，只能在外部进行更新。</p>
            <p>点击编辑器上的工具栏 <span class="ke-icon-holder" style="width: 16px; height: 16px; display: inline-block;"></span> 试试吧！如果要了解实现，请查看本页面源码。</p>
        </div>
        <div class="row">
            <div class="col-md-7">
                <textarea id="content" name="content" class="form-control kindeditor" style="height:500px;">Hello, world!</textarea>
                <br>
                </div>
            <div class="col-md-5">
                <textarea id="content2" readonly name="content2" class="form-control" style="height:500px;">Hello, world!</textarea>
            </div>
        </div>
    </div>

    <div class="modal fade" id="holderModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
                            class="sr-only">关闭</span></button>
                    <h4 class="modal-title" id='holderModalTitle'>添加 Holder</h4>
                </div>
                <div class="modal-body">
                    <div class="form-group">
                        <label for="holderText">请输入在界面上显示的文本</label>
                        <input id="holderText" type="text" class="form-control">
                    </div>
                    <div class="form-group">
                        <label for="holderValue">请输入要隐藏的内容</label>
                        <textarea class="form-control" name="holderValue" id="holderValue" cols="30" rows="10"></textarea>
                    </div>
                    <div class="form-group">
                        <label for="holderId">ID</label>
                        <input id="holderId" type="text" class="form-control">
                    </div>
                    <div class="form-group">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox" id="holderAsBlock"> 作为区块（单独占一行）
                            </label>
                        </div>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
                    <button type="button" class="btn btn-primary" id='holderSaveBtn'>保存</button>
                </div>
            </div>
        </div>
    </div>

    <script src="../../assets/jquery.js"></script>
    <script src="../../dist/js/zui.js"></script>
    <script src="../../dist/lib/kindeditor/kindeditor.js"></script>

    <style>
    /* 添加 holder 插件相关样式 */
    .ke-icon-holder {background: none; border: 1px solid red; text-align: center; border-radius: 50%; background-color: red; line-height: 14px;}
    .ke-icon-holder:before {content: 'H'; font-size: 14px; font-weight: bold; color: #fff;}
    </style>
    <script>
        // 添加 Holder 插件
        KindEditor.plugin('holder', function(K) {
            var self = this;

            if (!self.options.htmlTags) {
                self.options.htmlTags = {};
            }
            if (!self.options.htmlTags.div) {
                self.options.htmlTags.div = [];
            }
            if (!self.options.htmlTags.span) {
                self.options.htmlTags.span = [];
            }
            self.options.htmlTags.div.push('data-holder', 'data-holder-edit', 'contenteditable');
            self.options.htmlTags.span.push('data-holder', 'data-holder-edit', 'contenteditable');

            self.afterCreate(function() {
                $(self.edit.doc.head).append([
                    '<style>',
                    '.holder-element {border: 1px solid #ea644a; background: #ffe5e0; border-radius: 4px; padding: 0 5px; cursor: pointer; color: #ea644a; position: relative; min-width: 50px; text-align: center}',
                    '.holder-value {width: 20px; font-size: 0; position: absolute; top: 0; right: 0; bottom: 0;}',
                    '.holder-element:before {content: attr(data-holder)}',
                    '.holder-block {display: block; text-align: center}',
                    '.holder-span {display: inline-block; line-height: 1}',
                    '.holder-value:after {content: "X"; display: block; position: absolute; right: 0; top: 0; bottom: 0; border-radius: 0 3px 3px 0; background: #ffe5e0; text-align: center; font-size: 14px; display: flex; justify-content: center; align-items: center; width: 20px; border-left: 1px solid #ea644a; opacity: 0}',
                    '.holder-element:hover .holder-value:after {opacity: 1}',
                    '.holder-value:hover:after {background: #ea644a; color: #fff}',
                    '</style>'
                ].join('\n'));

                $(self.edit.doc).find('.holder-element[contenteditable="true"]').attr('contenteditable', false);

                if (self.options.holderEdit) {
                    $(self.edit.doc).on('click', '.holder-element', function(e) {
                        var $ele = $(this);
                        if($(e.target).is('.holder-value')) {
                            $ele.remove();
                            self.sync();
                            return;
                        }
                        showHolderEditModal($ele.attr('data-holder'), $ele.find('.holder-value').text(), $ele.hasClass('holder-block'), $ele.attr('id'), function(text, value, asBlock, id) {
                            var useDiv = asBlock && !self.options.blockUseSpan;
                            var $holderElement = $(useDiv ? '<div>' : '<span>').attr('data-holder', text).attr('contenteditable', false).addClass(asBlock ? 'holder-block' : 'holder-span').addClass('holder-element');
                            if(id) $holderElement.attr('id', id);
                            $holderElement.append($(useDiv ? '<div>' : '<span>').addClass('holder-value').text(value));
                            $ele.replaceWith($holderElement);
                            self.edit.focus();
                            self.sync();
                        });
                    });
                }
            });

            // 点击图标时执行
            self.clickToolbar('holder', function() {
                showHolderEditModal('', '', false, '', function(text, value, asBlock, id) {
                    var useDiv = asBlock && !self.options.blockUseSpan;
                    var $holderElement = $(useDiv ? '<div>' : '<span>').attr('data-holder', text).attr('contenteditable', false).addClass(asBlock ? 'holder-block' : 'holder-span').addClass('holder-element');
                    if(id) $holderElement.attr('id', id);
                    $holderElement.append($(useDiv ? '<div>' : '<span>').addClass('holder-value').text(value));
                    self.insertHtml($holderElement[0].outerHTML + '&nbsp;' + (useDiv ? '<br>' : ''));
                });
            });
        });

        function showHolderEditModal(placeholder, value, asBlock, id, callback) {
            if (typeof placeholder === 'function') {
                callback = placeholder;
                placeholder = '';
                value = '';
                id = '';
                asBlock = false;
            }
            placeholder = placeholder || '';
            value = value || '';
            $('#holderText').val(placeholder);
            $('#holderValue').val(value);
            $('#holderId').val(id);
            $('#holderAsBlock').prop('checked', !!asBlock);
            $('#holderModal').modal('show');
            $('#holderSaveBtn').off('click').on('click', function() {
                if (callback) {
                    callback($('#holderText').val(), $('#holderValue').val(), $('#holderAsBlock').is(':checked'), $('#holderId').val())
                }
                $('#holderModal').modal('hide');
            });
        };

        // 初始化 KindEditor
        $(function () {
            $('#content').val([
                '<h1 style="text-align:center;">项目进度报告</h1>',
                '<p>本文将介绍项目<span data-holder="$projectName" contenteditable="true" class="holder-span holder-element"><span class="holder-value">{{$projectName}}</span></span>&nbsp;的任务在本周&nbsp;<span data-holder="$weekTime" contenteditable="false" class="holder-span holder-element"><span class="holder-value">{{$weekTime}}</span></span>&nbsp; 进展情况。</p>',
                '<h2>已完成的任务</h2>',
                '<span data-holder="$finishTaskList" contenteditable="false" class="holder-block holder-element">',
                '<span class="holder-value">{{此处打印已完成的任务列表}}</span>',
                '</span>',
                '&nbsp;',
                '<h2>未完成的任务</h2>',
                '<p><br /></p>',
                '<span data-holder="$waitTaskList" contenteditable="false" class="holder-block holder-element">',
                '<span class="holder-value">{{$waitTaskList}}</span>',
                '</span>',
                '&nbsp;',
                '<p><br /></p>',
                '&nbsp;',
                '<p>',
                '<table class="table table-kindeditor ke-select-col" style="width:100%;">',
                '    <tbody>',
                '    <tr>',
                '        <td style="border:1px solid #ddd;" class="">报告人<br /></td>',
                '        <td style="border:1px solid #ddd;"><span data-holder="$userName" contenteditable="false" class="holder-span holder-element"><span class="holder-value">{{$userName}}</span></span>&nbsp;<br /></td>',
                '    </tr>',
                '    <tr>',
                '        <td style="border:1px solid #ddd;" class="">报告时间</td>',
                '        <td style="border:1px solid #ddd;"><span data-holder="$time" contenteditable="false" class="holder-span holder-element"><span class="holder-value">{{$time}}</span></span>&nbsp;<br /></td>',
                '    </tr>',
                '    </tbody>',
                '</table>',
                '<br />',
                '</p>',
            ].join('\n'));


            const toolbarItems = [
                    // 添加 Holder 插件图标
                    'holder', '|',
                    'source', '|', 'undo', 'redo', '|', 'preview', 'code', 'cut', 'copy', 'paste', '|', 'justifyleft', 'justifycenter', 'justifyright',
                    'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'quickformat', 'selectall', '|', 'fullscreen', '/',
                    'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
                    'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'table', 'hr', 'emoticons', 'pagebreak',
                    'link', 'unlink', '|'
            ];

            window.$editor = KindEditor.create('textarea.kindeditor', {
                wellFormatMode: true,
                simpleWrap: true,
                indentChar: '  ',
                width: '100%',
                basePath: '../../dist/lib/kindeditor/',
                allowFileManager: true,
                bodyClass: 'article-content',
                cssPath: '../../dist/css/zui.css',
                placeholder: '请输入文章内容\nGood Luck!',
                transferTab: true,
                afterChange: function(e) {
                    $('#content2').val(this.edit.html());
                },
                items: toolbarItems,

                // 启用编辑 holder 功能
                holderEdit: true,

                // 单独占一行的 holder 使用 span
                blockUseSpan: true,

                // 当创建 holder 时的回调函数
                onCreateHolder: function($holder) {

                }
            });
        });
    </script>
</body>

</html>
